<template>
    <div class="">
        <div class="box box-primary">
          <div class="box-header">
            <h4 class="text-primary text-center">设备录像({{ name }})-列表视图</h4>
          </div>
          <div class="box-body">
            <div class="form-inline" autocomplete="off" spellcheck="false">
              <div class="form-group form-group-sm">
                <button type="button" class="btn btn-sm btn-primary" @click.prevent="$router.go(-1)" v-if="$getQueryString('menu', 'yes') != 'no'">
                  <i class="fa fa-chevron-left"></i> 返回
                </button>
              </div>
              <div class="form-group pull-right">
                  <div class="input-group input-group-sm">
                      <DatePicker class="form-control" @update:day="updateDay" :day="day" ref="datePicker"></DatePicker>
                      <div class="input-group-btn">
                          <button type="button" class="btn btn-sm btn-default" @click.prevent="showDatePicker">
                            <i class="fa fa-calendar"></i>
                          </button>
                          <button @click.prevent="toTimeView" class="btn btn-default btn-sm">
                              <i class="fa fa-hand-o-right"></i> 时间轴视图
                          </button>
                      </div>
                  </div>
              </div>
            </div>
            <br>
            <div class="clearfix"></div>
            <el-table stripe v-loading="loading" element-loading-text="加载中..."
              ref="playbackTable" :data="pageData" :default-sort="{prop: 'StartTime', order: 'ascending'}" @sort-change="sortChange">
              <el-table-column prop="FileName" label="文件名" min-width="220" :formatter="formatName" show-overflow-tooltip></el-table-column>
              <el-table-column label="操作" min-width="150" :fixed="isMobile() ? false : 'right'">
                <template slot-scope="props">
                    <div class="btn-group btn-group-xs">
                        <button type="button" class="btn btn-primary" @click.prevent="startPlayback(props.row)" :disabled="props.row.Starting"><i class="fa fa-play-circle"></i> 播放</button>
                        <button type="button" class="btn btn-info" @click.prevent="downloadPlayback(props.row)" :disabled="props.row.Starting"><i class="fa fa-download"> 下载</i></button>
                    </div>
                </template>
              </el-table-column>
              <el-table-column prop="FileSize" label="文件大小" min-width="100" :formatter="formatSize" show-overflow-tooltip></el-table-column>
              <el-table-column prop="StartTime" label="开始时间" min-width="160" :formatter="formatName" sortable></el-table-column>
              <el-table-column prop="EndTime" label="结束时间" min-width="160" :formatter="formatName" sortable></el-table-column>
            </el-table>
          </div>
          <div class="box-footer clearfix" v-if="total > 0">
            <el-pagination layout="total,prev,pager,next" :pager-count="isMobile() ? 3 : 5" class="pull-right" :total="total" :page-size.sync="pageSize" :current-page.sync="currentPage"></el-pagination>
          </div>
        </div>
        <PlaybackVideoDlg ref="playbackVideoDlg" live @close="onClose"></PlaybackVideoDlg>
        <PlaybackDownloadDlg ref="playbackDownloadDlg" @download="onDownload"></PlaybackDownloadDlg>
    </div>
</template>

<script>
import _ from "lodash";
import moment from "moment";
import DatePicker from "components/DatePicker.vue";
import PlaybackVideoDlg from "components/PlaybackVideoDlg.vue";
import PlaybackDownloadDlg from "components/PlaybackDownloadDlg.vue";
import { mapState } from "vuex";
import prettyBytes from "pretty-bytes";

export default {
  props: {
    id: {
      type: String,
      default: ""
    },
    mode: {
      type: String,
      default: "listview"
    },
    day: {
      type: String,
      default: () => moment().format("YYYYMMDD")
    }
  },
  data() {
    return {
      timerange: [
        moment(this.day, "YYYYMMDD").startOf('hour').toDate(),
        moment(this.day, "YYYYMMDD").startOf('hour').toDate()
      ],
      currentPage: 1,
      pageSize: 10,
      loading: false,
      sort: "",
      order: "",
      name: "",
      osd: "",
      protocol: "",
      streamID: "",
      records: []
    };
  },
  components: {
    PlaybackVideoDlg, PlaybackDownloadDlg, DatePicker
  },
  computed: {
    ...mapState(['userInfo', 'serverInfo']),
    total() {
        return this.records.length;
    },
    pageData() {
        let start = (this.currentPage - 1) * this.pageSize;
        let end = start + this.pageSize;
        return this.records.slice(start, end);
    }
  },
  methods: {
    ready(){
      this.$watch('day', function(newVal, oldVal) {
        this.timerange = [
          moment(this.day, "YYYYMMDD").startOf('hour').toDate(),
          moment(this.day, "YYYYMMDD").startOf('hour').toDate()
        ]
      });
      console.log(this.id, this.day);
      this.getRecords(true);
      $(window).on("beforeunload", this.beforeUnload);
    },
    isMobile() {
      return videojs.browser.IS_IOS || videojs.browser.IS_ANDROID;
    },
    showDatePicker() {
      $(this.$refs.datePicker.$el).focus();
    },
    updateDay(day) {
      this.$nextTick(() => {
        this.$router.replace({
          path: `/playback/${this.mode}/${this.id}/${day}`,
          query: Object.assign({}, this.$route.query),
        });
      })
    },
    nextTimeRange() {
      var end = moment(this.day, "YYYYMMDD").endOf('day');
      var now = moment().startOf("second");
      if(end.isAfter(now, "second")) {
        end = now;
      }
      var r1 = moment(this.timerange[1]);
      if(r1.isSameOrAfter(end, "second")){
        return false;
      }
      var r2 = moment(this.timerange[1]).add(6, 'hours');
      if(r2.isAfter(end)) {
        r2 = end;
      }
      if(r2.clone().startOf("minute").isSameOrBefore(r1.clone().startOf("minute"), "second")) {
        return false;
      }
      console.log(r1.format("YY-MM-DD HH:mm:ss"), "~", r2.format("YY-MM-DD HH:mm:ss"), "loading...");
      this.timerange = [r1.toDate(), r2.toDate()];
      return true;
    },
    getRecords(refresh) {
      if(refresh) {
        this.loading = true;
        this.records = [];
        this.currentPage = 1;
      }
      if(!this.nextTimeRange()){
        this.sortRecords();
        this.$nextTick(() => {
          this.loading = false;
        })
        return
      }
      $.ajax("/api/v1/playback/record/list", {
        method: "GET",
        global: false,
        data: {
          channel: this.id,
          starttime: moment(this.timerange[0]).format("YYYY-MM-DD HH:mm:ss"),
          endtime: moment(this.timerange[1]).format("YYYY-MM-DD HH:mm:ss")
        }
      }).then(ret => {
        if(!this.name && ret.ChannelName) {
          this.name = ret.ChannelName;
        }
        if(!this.osd && ret.ChannelOSD) {
          this.osd = ret.ChannelOSD;
        }
        var items = ret.RecordList || [];
        this.records = this.records.concat(items.filter(item => {
          if(!item || !item.StartTime || !item.EndTime) {
            return false;
          }
          if(this.records.some(v => (v.StartTime === item.StartTime && v.EndTime === item.EndTime))) {
            console.log("repeat", item.StartTime, "~", item.EndTime);
            return false;
          }
          return true;
        }));
      }).always(() => {
        this.$nextTick(() => {
          this.getRecords(false);
        })
      });
    },
    formatName(row, col, cell) {
      if (cell) return cell;
      return "-";
    },
    formatSize(row, col, cell) {
      if(isNaN(cell)) return "-";
      return prettyBytes(cell);
    },
    downloadPlayback(row) {
      this.loading = true;
      this.$set(row, "Starting", true);
      $.get("/api/v1/playback/start", {
        channel: this.id,
        starttime: row.StartTime,
        endtime: row.EndTime,
        protocol: "MP4",
      }).then(streamInfo => {
        this.streamID = streamInfo.StreamID;
        this.$refs["playbackDownloadDlg"].download(row.StartTime + " - " + row.EndTime, streamInfo.StreamID);
      }).always(() => {
        this.$nextTick(() => {
          this.loading = false;
        })
        this.$delete(row, "Starting");
      });
    },
    startPlayback(row) {
      this.loading = true;
      this.$set(row, "Starting", true);
      $.get("/api/v1/playback/start", {
        channel: this.id,
        starttime: row.StartTime,
        endtime: row.EndTime,
        protocol: this.protocol,
      }).then(streamInfo => {
        this.streamID = streamInfo.StreamID;
        this.$refs["playbackVideoDlg"].play(
          this.protocol,
          streamInfo.StreamURL || "",
          row.StartTime + " - " + row.EndTime,
          streamInfo.SnapURL || "",
          this.id,
          streamInfo.StreamID || "",
          this.osd
        );
      }).always(() => {
        this.$nextTick(() => {
          this.loading = false;
        })
        this.$delete(row, "Starting");
      });
    },
    stopPlayback() {
      return new Promise((resolve, reject) => {
          if(!this.streamID) {
            resolve();
            return
          }
          $.ajax({
            method: "GET",
            url: "/api/v1/playback/stop",
            global: false,
            data: {
              streamid: this.streamID
            }
          }).always(() => {
            resolve();
          })
          this.streamID = "";
      })
    },
    beforeUnload(event) {
      this.stopPlayback();
      // event.preventDefault();
      event.returnValue = '';
    },
    toTimeView() {
      this.$router.replace({
        path: `/playback/timeview/${this.id}/${this.day}`,
        query: Object.assign({}, this.$route.query),
      });
    },
    sortChange(data) {
      if(!data || !data.prop || !data.order) return;
      this.sort = data.prop;
      this.order = data.order;
      this.sortRecords();
    },
    sortRecords() {
      if(!this.sort) return;
      this.records.sort((x, y) => {
        var t1 = x[this.sort];
        var t2 = y[this.sort];
        var ret = 0;
        if(!t1 || !t2) return ret;
        if(t1 < t2) {
          ret = -1;
        } else if(t1 > t2) {
          ret = 1;
        }
        if(this.order === "desc" || this.order === "descending") {
          ret = -1 * ret;
        }
        return ret;
      })
    },
    onDownload() {
      this.streamID = "";
    },
    onClose() {
      this.streamID = "";
    },
  },
  mounted() {
    this.protocol = this.$getQueryString("protocol", "");
  },
  beforeDestroy() {
    $(window).off("beforeunload", this.beforeUnload);
    this.stopPlayback();
  },
  beforeRouteLeave(to, from, next) {
    this.stopPlayback();
    next();
  },
  beforeRouteEnter(to, from, next) {
    next(vm => {
      if(to.query.protocol) {
        vm.protocol = to.query.protocol;
      }
      vm.ready();
    })
  },
  beforeRouteUpdate(to, from, next) {
    if (!to.params.day) {
      next({
        path: `/playback/${this.mode}/${this.id}/${moment().format('YYYYMMDD')}`,
        query: Object.assign({}, this.$route.query),
        replace: true
      })
      return;
    }
    if(to.query.protocol) {
      this.protocol = to.query.protocol;
    }
    this.stopPlayback();
    next();
    this.$nextTick(() => {
      if(!this.loading && from.path != to.path) {
        console.log(this.id, this.day);
        this.getRecords(true);
      }
    })
  }
};
</script>
